/*
 *    This file is part of CeluMap.
 *
 *    CeluMap is free software; you can redistribute it and/or modify
 *    it under the terms of the GNU Lesser General Public License as published by
 *    the Free Software Foundation; either version 3 of the License, or
 *    (at your option) any later version.
 *
 *    CeluMap is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *    GNU Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public License
 *    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 *    Copyright 2006, 2007, 2008 Gonzalo Merayo
 *    gonzalo (at) celumap.com.ar
 *    www.celumap.com.ar
 *
 */

package figures.basic;

import figures.Colors;
import figures.Figure;
import geometry.Matrix;
import geometry.MovingTransform;
import geometry.Point;
import geometry.Rectangle;

import screen.GisGraphics;

import map.file.FileConstants;

public class PoliLine extends Rectangle implements Figure{

	public int ix;
	public int iy;
	public NameManager nm = null;
	public int namepos = 0;
	public int offsetinit = 0;
	public int l = 0;
	
	public byte getColor(){
		return 0;
	}
	
	public PoliLine(Point[] p, String name){
		int[] x = new int[p.length];
		int[] y = new int[p.length];
		for(int i=0;i<p.length;i++){
			x[i] = p[i].x;
			y[i] = p[i].y;
		}
		nm = new NameManager();
		setxy(x, y);
		setName(name);
	}
	
	public PoliLine(NameManager n) {
		nm = n;
	}
	
	public PoliLine() {
		nm = new NameManager();
	}

	public void changeOffsetManager(NameManager o){
		byte[] b = new byte[l*2];
		System.arraycopy(nm.buffer, offsetinit, b, 0, l*2);
		offsetinit = o.addOffsets(b);
		b = nm.getName(namepos);
		namepos = o.addName(b);
		nm = o;
	}
	
	public boolean equals(Object o){
		if(o==null || o.getClass() != this.getClass())
			return false;
		PoliLine p = (PoliLine)o;
		if(ix!=p.ix || iy!=p.iy || l != p.l /*|| n.length!=p.n.length*/)
			return false;
		/*for(int i=0;i<n.length;i++)
			if(n[i]!=p.n[i])
				return false;*/
		/*for(int i=0;i<vx.length;i++)
			if(vx[i] != p.vx[i] || vy[i] != p.vx[i])
				return false;*/
		return true;
	}

	static int x0, y0, x1, y1, x2, y2, ox, oy;
	static byte[] v;
	public void drawIn(GisGraphics g, Rectangle area, MovingTransform transform) {
		g.setColor(getColor());
		drawInIgnoreColor(g, area, transform);
	}

	/**
	 * @param g
	 * @param area
	 * @param transform
	 */
	private void drawInIgnoreColor(GisGraphics g, Rectangle area, MovingTransform transform) {
		x1 = x0 = transform.mapX2screen(ix,iy);
		y1 = y0 = transform.mapY2screen(ix,iy);
		long z = transform.getZoom();
		ox = 0;
		oy = 0;
		v = nm.buffer;
		for(int i=offsetinit;i<(offsetinit+l);i++)
		{
			ox += v[i];
			oy += v[i+l];
			x2 = x0 + (int)((z*ox)>>Matrix.nshift);
			y2 = y0 + (int)((z*oy)>>Matrix.nshift);
			if(((x1 <= area.bbxf) || (x2 <= area.bbxf))
			&& ((area.bbxi <= x1) || (area.bbxi <= x2))
			&& ((y1 <= area.bbyf) || (y2 <= area.bbyf))
			&& ((area.bbyi <= y1) || (area.bbyi <= y2)))//area.colides(x1, y1, x2, y2)
				g.drawLine(x1, y1, x2, y2);
			x1 = x2;
			y1 = y2;
		}
	}
	
	public void prepareBoundingBox() {
		bbxi = bbxf = x2 = ix;
		bbyi = bbyf = y2 = iy;
		for(int i=0;i<l;i++){
			x2 += nm.buffer[offsetinit+i];
			y2 += nm.buffer[offsetinit+i+l];
			if(bbxi > x2) bbxi = x2;
			if(bbxf < x2) bbxf = x2;
			if(bbyi > y2) bbyi = y2;
			if(bbyf < y2) bbyf = y2;
		}
	}
	
	public byte getType() {
		return FileConstants.FIG_TYPE_POLI;
	}
 
	public Rectangle getBoundingBox() {
		return this;
	}
	/*
	public String toString(){
		return super.toString();
		StringBuffer s = new StringBuffer(" xi:"+ix+" yi:"+iy);
		for(int i=0;i<l;i++)
			s.append(" x:"+nm.buffer[offsetinit+i]+" y:"+nm.buffer[offsetinit+l+i]);
		return getClass().toString()+s.toString();
		
	}
*/
	public void setId(int i) {
		//id = i;
	}

	public int getId() {
		//return id;
		return 0;
	}

	public byte[] getName() {
		return nm.getName(namepos);
	}
	
	public void setName(String name){
		NameManager tmp = new NameManager();
		byte[] b = new byte[l*2];
		System.arraycopy(nm.buffer, offsetinit, b, 0, l*2);
		offsetinit = tmp.addOffsets(b);
		namepos = tmp.addName(name.getBytes());
		nm = tmp;
		
	}
	
	public void drawVolatileIn(GisGraphics g, Rectangle area, MovingTransform transform, boolean highlight, int frame) {
		if(highlight&&((frame%2)==0)){
			g.setColor(Colors.highlight);
			drawInIgnoreColor(g, area, transform);
		}else
			g.setColor((byte)0);
		int x = transform.mapX2screen(ix,iy);
		int y = transform.mapY2screen(ix,iy);
		if(area.colides(x,y)){
			if(nm.buffer[offsetinit]>0)
				g.drawString(getName(), x, y, nm.buffer[offsetinit], nm.buffer[offsetinit+l]);
			else
				g.drawString(getName(), x, y, -nm.buffer[offsetinit], -nm.buffer[offsetinit+l]);
		}
	}
	
	public int[] getx() {
		int[] r = new int[l+1];
		r[0] = ix;
		for(int j=1;j<r.length;j++){
			r[j] = r[j-1]+nm.buffer[offsetinit+j-1];
		}
		return r;
	}

	public int[] gety() {
		int[] r = new int[l+1];
		r[0] = iy;
		for(int j=1;j<r.length;j++){
			r[j] = r[j-1]+nm.buffer[offsetinit+j-1+l];
		}
		return r;
	}
	
	public void setxy(int[] x, int[] y){
		NameManager tmp = new NameManager();
		namepos = tmp.addName(nm.getName(namepos));
		nm = tmp;
		l = x.length;
		offsetinit = 0;
		ix = x[0];
		iy = y[0];
		for(int i=1;i<l;i++){
			int d = Math.max(Math.abs(x[i-1]-x[i]), Math.abs(y[i-1]-y[i]));
			if(d>127){
				int n = (d/127)+1;
				for(int j=1;j<=n;j++)
					addCoord((byte)((((x[i]-x[i-1])*j)/n)-(((x[i]-x[i-1])*(j-1))/n)), (byte)((((y[i]-y[i-1])*j)/n)-(((y[i]-y[i-1])*(j-1))/n)));
			}else{
				addCoord((byte)(x[i]-x[i-1]), (byte)(y[i]-y[i-1]));
			}
		}
		l = nm.buffer.length/2;
		prepareBoundingBox();
	}

	private void addCoord(byte i, byte j) {
		byte[] tmp = new byte[nm.buffer.length+2];
		System.arraycopy(nm.buffer, 0, tmp, 0, nm.buffer.length/2);
		System.arraycopy(nm.buffer, nm.buffer.length/2, tmp, nm.buffer.length/2+1, nm.buffer.length/2);
		nm.buffer=tmp;
		nm.buffer[nm.buffer.length/2-1]=i;
		nm.buffer[nm.buffer.length-1]=j;
	}

	
}
